﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using SkinnedModel;
using System.Xml;
using System.IO;
using Primitives3D;
using Particle3DEffect;
using FighterLibrary;

// -----------------------------------------------------------------------
// <copyright file="$safeitemrootname$.cs" company="$registeredorganization$">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
namespace ObjectLibrary
{
    public abstract class Fighter : VisibleGameEntity3D
    {
        public const int MAX_HP = 100;
        public const int MAX_PP = 100;

        public enum State { idle, run, actack, free, hurt, actackRe, block, jump, defend, jumpOnAir, land, dead, repawn, throwEnergySphere };
        protected PhysicalEngine _physical = new PhysicalEngine();
        protected bool _isOnGround = true;
        protected bool _isMoveOnAir = false;
        protected State _currentState;
        protected float _lookRotationY=0;
        protected float _lookRotationZ = 0;
        protected float _runRotation = 0;
        protected float _currentRotation = 0;
        protected Vector3 _currentPosition = Vector3.Zero;
        protected Vector3 _tartgetPosition;
        protected Vector3 _dPosition = Vector3.Zero;
        protected float _targetLookRotation;
        protected float _lastLookRotation;
        private bool _tacked;
        private Move _lastMove;
        private Aura _aura;
        private Random gameRandom;
        private double currentTime = 0;
        private bool isPlayHitSound = false;
        private int _team;

        public int Team
        {
            get { return _team; }
            set { _team = value; }
        }

        private List<EnergySphere> energySpheres;
        private ParticleSystem _energyShield;
        List<Vector3> _explosionSoundPoint;
        private double regenTime = 300;

        public List<EnergySphere> EnergySpheres
        {
            get { return energySpheres; }
            set { energySpheres = value; }
        }

        public ParticleSystem EnergyShield
        {
            get { return _energyShield; }
            set { _energyShield = value; }
        }

        private double repawnTime;

        public double RepawnTime
        {
            get { return repawnTime; }
            set { repawnTime = value; }
        }


        public Aura Aura
        {
            get { return _aura; }
            set { _aura = value; }
        }

        public bool Tacked
        {
            get { return _tacked; }
            set { _tacked = value; }
        }

        public Vector3 CurrentPosition
        {
            get { return _currentPosition; }
            set { _currentPosition = value; }
        }
        protected AnimationPlayer _animationPlayer;
        protected SkinningData _skinningData;

        protected string _name;

        protected float _speed = 0.2f;
        protected float _jumpHeight = 50;
        protected double _actionTimeSpan;

        protected int _strength;
        protected int _hp;
        protected int _pp;

        protected int _kill;
        protected int _die;
        private SoundEffect _footStepSound;

        public SoundEffect FootStepSound
        {
            get { return _footStepSound; }
            set { _footStepSound = value; }
        }
        private SoundEffect _explosionSound;

        public SoundEffect ExplosionSound
        {
            get { return _explosionSound; }
            set { _explosionSound = value; }
        }
        private SoundEffect _hitSound;

        public SoundEffect HitSound
        {
            get { return _hitSound; }
            set { _hitSound = value; }
        }

         public int Kill
        {
            get { return _kill; }
            set { _kill = value; }
        }
        
         public int Die
        {
            get { return _die; }
            set { _die = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public int Hp
        {
            get { return _hp; }
            set { _hp = value;
                if (_hp < 0)
                    _hp = 0;
                else if (_hp > MAX_HP)
                    _hp = MAX_HP;
            }
        }
        public int Pp
        {
            get { return _pp; }
            set {
 
                _pp = value;
                if (_pp < 0)
                    _pp = 0;
                else if (_pp > MAX_PP)
                    _pp = MAX_PP;
            }
        }

        protected Move _firstMove;
        protected Move _currentMove;
        private List<Move.Strike> _comboQueue;

        protected SkinnedSphere[] skinnedSpheres;
        protected BoundingSphere[] boundingSpheres;
        protected BoundingSphere[] _hand;
        protected BoundingSphere[] _leg; 
        protected BoundingSphere[] _body;


        protected SpherePrimitive spherePrimitive; 

        public float RunRotation
        {
            get { return _runRotation; }
            set { _runRotation = value; }
        }


        public float LookRotationY
        {
            get { return _lookRotationY; }
            set {
                
                _lookRotationY = value; 
            }
        }
        public float LookRotationZ
        {
            get { return _lookRotationZ; }
            set {
                if (value > MathHelper.ToRadians(-80) && value < MathHelper.ToRadians(80)) 
                    _lookRotationZ = value;
            }
        }



        public int Strength
        {
            get { return _strength; }
            set { _strength = value; }
        }
        public State CurrentState
        {
            get { return _currentState; }
            //set { _currentState = value; }
        }
        public virtual bool IsEnableToActack()
        {
            return (_currentState == State.free || _currentState == State.run || _currentState == State.idle);
        }
        public void AddToComboQueue(Move.Strike strike)
        {
            if(_currentState != State.actackRe)
                _comboQueue.Add(strike);
        }

        protected void Init()
        {
            _name = "";
            repawnTime = 10000;
            _hp = MAX_HP;
            _pp = MAX_PP;
            Position = Vector3.Zero;
            _currentState = State.free;          
            Idle();
            _animationPlayer.Update(new TimeSpan(0), true, Matrix.Identity);
            _comboQueue = new List<Move.Strike>();
            gameRandom = new Random();
            EnergySpheres = new List<EnergySphere>();
            _explosionSoundPoint = new List<Vector3>();
        }

        protected void PlayAction(string actionName)
        {
            if (actionName.Length == 0)
                return;
            _actionTimeSpan = 0;
            AnimationClip clip = _skinningData.AnimationClips[actionName];
            _animationPlayer.StartClip(clip);
            
        }
        public virtual void Idle()
        {
            if (CurrentState != State.free && CurrentState != State.run && CurrentState != State.defend)
                return;
            PlayAction("Idle");
            _currentState = State.idle;
        }
        public virtual void Defend()
        {
            if (CurrentState != State.idle && CurrentState != State.run )
                return;
            PlayAction("Defend");
            _currentState = State.defend;
        }
        public virtual void Jump()
        {
            if (CurrentState != State.idle && CurrentState != State.run && CurrentState != State.defend)
                return;
            PlayAction("Jump");
            _currentState = State.jump;
        }
        public virtual void Run()
        {
            if (_currentState == State.jumpOnAir)
            {
                _isMoveOnAir = true;
                return;
            }
            if (CurrentState != State.idle && CurrentState != State.free && CurrentState != State.defend)
                return;
            
            PlayAction("Run");
            _currentState = State.run;
        }
        public virtual void Actack()
        {
            if ((CurrentState != State.idle && CurrentState != State.free && CurrentState != State.defend && CurrentState != State.run)
                 || _comboQueue.Count == 0)
                return;
            _currentMove = new Move(_firstMove.getMove(_comboQueue[0]));
            startAStrike(_currentMove);
            _currentState = State.actack;
            
        }
        public virtual void Hurt()
        {
            /*if (CurrentState == State.hurt)
                return;*/
            _comboQueue.Clear();
            Position = _currentPosition;
            _dPosition = Vector3.Zero;
            PlayAction("Hurt");

            _currentState = State.hurt;
        }
        public void Dead()
        {
            if (_currentState == State.dead)
                return;
            _currentState = State.dead;
            _actionTimeSpan = 0;
            ((MySkinning3DModel)_model).Anlpha = 0.6f;
            //_lookRotationZ = -MathHelper.PiOver2;
        }
        public void PlaySoundEffects(Vector3 listenPos)
        {
            Vector3 temp = listenPos - _currentPosition;
            
            float volume= 1.0f-temp.Length()/60;
            if(volume<0)
                volume = 0;
            if (_currentState == State.run )
            {
                if (_animationPlayer.CurrentTime.Milliseconds > _animationPlayer.CurrentClip.Duration.Milliseconds - 42)
                    FootStepSound.Play(volume, 0, 0);
            }
            else if (isPlayHitSound)
            {
                HitSound.Play(volume, 0, 0);
                isPlayHitSound = false;
            }
            for (int i = 0; i < _explosionSoundPoint.Count;i++ )
            {
                temp = listenPos - _explosionSoundPoint[i];

                volume = 1.0f - temp.Length() / 60;
                if (volume < 0)
                    volume = 0;
                ExplosionSound.Play(volume, 0, 0);
            }
            _explosionSoundPoint.Clear();
        }
        public void Repawn()
        {
            if (_currentState == State.repawn)
                return;
            //_currentState = State.repawn;
            _currentState = State.free;
            Idle();
            _actionTimeSpan = 0;
            ((MySkinning3DModel)_model).Anlpha = 1f;
            _physical.Velocity = Vector3.Zero;
            _hp = MAX_HP;
            _pp = MAX_PP;
        }
        bool isFired = false;

        public bool IsFired
        {
            get { return isFired; }
            set { isFired = value; }
        }
        public void ThrowEnergySphere(Vector3 cameraTarget)
        {
            if (_pp >= EnergySphere.MANA_PER_THROW)
            {
                Vector3 direction = cameraTarget - CurrentPosition;
                direction.Normalize();
                Vector3 distance = 3 * direction;
                energySpheres[energySpheres.Count - 1].SetStart(CurrentPosition + new Vector3(0, 2, 0)+distance, cameraTarget - CurrentPosition, 80);
                _pp -= EnergySphere.MANA_PER_THROW;
                isFired = true;
            }
        }
        public override void Draw(GameTime gameTime, GraphicsDevice graphicsDevice, Effect effect, MyCamera camera)
        {
            Matrix[] bones = _animationPlayer.GetSkinTransforms();
            
            ((MySkinning3DModel)_model).Draw(gameTime, graphicsDevice, camera, bones);
            if (Aura != null)
                Aura.Draw(gameTime, graphicsDevice, effect, camera);
        }

        private float getDRotation(float oldR, float newR, float sDR)
        {
            float dR = (newR - oldR) % MathHelper.TwoPi;

            if (dR > MathHelper.Pi)
            {
                dR = -(MathHelper.TwoPi - dR);
            }
            else if (dR < -MathHelper.Pi)
            {
                dR = (MathHelper.TwoPi + dR);
            }

            if (dR > sDR)
            {
                return sDR;
            }
            else if (dR < -sDR)
            {
                return -sDR;
            }
            return dR;
        }

        public void setHeight(float Y)
        {
            Vector3 newPos = Position;
            if (newPos.Y < Y + 2 * _speed)
            {
                if ((!_isOnGround && (CurrentState != State.jump)) 
                    || CurrentState == State.jumpOnAir)
                {
                    PlayAction("Land");
                    _currentState = State.land;
                    _isOnGround = true;
                }
                newPos.Y = Y;
                
                Position = newPos;
                _currentPosition.Y = Y;
            }
            else
            {
                _isOnGround = false;
            }
            
            
            
        }
        public void setForce(Vector3 forceVector, float forceLength)
        {
            forceVector.Normalize();
            forceVector = forceVector * forceLength;
            _physical.setForce(forceVector);
        }

        private void startAStrike(Move move)
        {
            _dPosition = _currentPosition - Position;

            _comboQueue.RemoveAt(0);
            PlayAction(move.ActionName);
            _tartgetPosition = Position + new Vector3((float)((move.DPosition.Z * (Math.Sin(RotationY))) + (move.DPosition.X * (Math.Sin(RotationY - MathHelper.PiOver2))))
                ,0
                , (float)((move.DPosition.Z * (Math.Cos(RotationY))) + (move.DPosition.X * (Math.Cos(RotationY - MathHelper.PiOver2)))));
            _lastLookRotation = _lookRotationY;
            _targetLookRotation = _lookRotationY + move.DRotation ;
        }



        public void Update(GameTime gameTime, Map map)
        {
            _tacked = false;

            _actionTimeSpan += gameTime.ElapsedGameTime.TotalMilliseconds;
            currentTime += gameTime.ElapsedGameTime.Milliseconds;
            if (currentTime >regenTime)
            {
                _pp += 1;
                currentTime = 0;
            }

            if (_currentState == State.dead)
            {
                _currentPosition.Y += 0.1f;
                Position = _currentPosition;
                ((MySkinning3DModel)_model).Anlpha -= 0.001f;
                if (_actionTimeSpan >= repawnTime)
                {
                    Repawn();
                    setAtHomePosition(map);
                }
                return;
            }
            for (int i = 0; i < energySpheres.Count; i++)
            {
                if (energySpheres[i].IsDead)
                    energySpheres.RemoveAt(i);
            }
            for (int i = 0; i < energySpheres.Count; i++)
            {
                energySpheres[i].UpdateEnergySphere(gameTime);
                if (map.getHeight(energySpheres[i].Position) > energySpheres[i].Position.Y)
                {
                    SetEnergyExplosion(energySpheres[i]);
                }
            }
            //if (_currentState == State.throwEnergySphere)
            //{
            //    if (_actionTimeSpan < energySphere.TimeSphereFly)
            //        energySphere.UpdateEnergySphere(gameTime, this);
            //    else
            //    {
            //        _currentState = State.free;
            //        Idle();
            //        _actionTimeSpan = 0;
            //        energySphere.VectorVelocitySphere = Vector3.Zero;
            //    }
            //}

            float Y = map.getHeight(_currentPosition);
            setHeight(Y);
            _physical.update(gameTime.ElapsedGameTime.TotalSeconds, _isOnGround);

            double t = _animationPlayer.CurrentClip.Duration.TotalMilliseconds - _actionTimeSpan;
            if (_currentState == State.run)
            {
                float newRotationY = _lookRotationY + _runRotation;
                    float d = getDRotation(RotationY, newRotationY, 0.4f);
                    RotationY += d;
                    Vector3 newPos = Position + new Vector3((float)(_speed * (Math.Sin(RotationY))), 0, (float)(_speed * (Math.Cos(RotationY))));
                    float newY = map.getHeight(newPos);
                    if (newY <= Y + 1.3 * _speed)
                        Position = newPos;

            }
            else if (_currentState == State.jumpOnAir && _isMoveOnAir)
            {
                _isMoveOnAir = false;
                Vector3 newPos = Position + new Vector3((float)(_speed * (Math.Sin(_lookRotationY + _runRotation))), 0
                    , (float)(_speed * (Math.Cos(_lookRotationY + _runRotation))));
                Position = newPos;
            }
            else if (_currentState == State.idle || _currentState == State.defend)
            {
                float newRotationY = _lookRotationY;
                float d = getDRotation(RotationY, newRotationY, 0.4f);
                RotationY += d;
            }
            else if (t <= 42)
            {
                if (_currentState == State.actack)
                {
                    _lastMove = _currentMove;
                    _tacked = true;

                    if (_comboQueue.Count == 0)
                    {
                        _comboQueue.Clear();
                        if (_currentMove != null)
                            PlayAction(_currentMove.ReActionName);
                        //_currentMove = _firstMove;
                        _currentState = State.actackRe;
                        setInBoundary(map);
                        return;
                    }
                    Move move = new Move(_currentMove.getMove(_comboQueue[0]));
                    if (move.hasValue())
                    {
                        _comboQueue.Clear();
                        if (_currentMove != null)
                            PlayAction(_currentMove.ReActionName);

                        _currentState = State.actackRe;
                        setInBoundary(map);
                        return;
                    }
                    _currentMove = move;
                    startAStrike(_currentMove);
                    setInBoundary(map);
                    return;
                }
                else if (_currentState == State.actackRe)
                {
                    if (_currentMove != null)
                    {
                        RotationY += _currentMove.DRotation;
                    }
                    _dPosition = Vector3.Zero;
                    Position = _tartgetPosition;
                    _currentPosition = Position;
                    _currentState = State.free;
                    Idle();
                }
                else if (CurrentState == State.hurt)
                {
                    _currentState = State.free;
                    Idle();
                }
                else if (CurrentState == State.jump)
                {
                    PlayAction("JumpOnAir");
                    _physical.setForce(new Vector3(0, _jumpHeight, 0));

                    _currentState = State.jumpOnAir;

                }
                else if (CurrentState == State.jumpOnAir)
                {

                    _currentPosition = Position;
                    Position = _physical.updatePosition(Position, gameTime.ElapsedGameTime.TotalSeconds);
                    UpdateBoundingSpheres();
                    return;
                }
                else if (CurrentState == State.land)
                {
                    _currentState = State.free;
                    Idle();
                }

            }
            if (_currentState == State.actack || _currentState == State.actackRe)
            {
                float percentTime = (float)(_actionTimeSpan / _animationPlayer.CurrentClip.Duration.TotalMilliseconds) / 2;
                float dPercentTime = (float)(gameTime.ElapsedGameTime.TotalMilliseconds / _animationPlayer.CurrentClip.Duration.TotalMilliseconds) / 2;
                if (_currentState == State.actackRe)
                    percentTime += 0.5f;

                float height = _currentPosition.Y;
                Vector3 dPos = _tartgetPosition - Position - _dPosition;
                _currentPosition = Position + _dPosition + percentTime * dPos;
                _currentPosition.Y = height;
                float dR = _targetLookRotation - _lastLookRotation;
                _lookRotationY += dR * dPercentTime;

                Position = _physical.updatePosition(Position, gameTime.ElapsedGameTime.TotalSeconds);

            }
            else
            {
                _currentPosition = Position;
                Position = _physical.updatePosition(Position, gameTime.ElapsedGameTime.TotalSeconds);
            }
            _animationPlayer.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);

            UpdateBoundingSpheres();
            if (Aura != null)
            {
                Vector3 posAura = _currentPosition;
                posAura.Y += 0.3f;
                Aura.Position = posAura;
                Aura.Update(gameTime);
            }
            if (isFired)
            {
                UpdateEnergyShield();
                isFired = false;
            }
            setInBoundary(map);
            //UpdateEnergySphere();
        }

        private void setAtHomePosition(Map map)
        {
            List<Vector2> positions=null;
            switch(Team)
            {
                case 0:
                    positions = map.HomeAPositions;
                    break;
                case 1:
                    positions = map.HomeBPositions;
                    break;
            }
            for (int i = 0; i < positions.Count; i++)
            {
                Vector2 pos = positions[gameRandom.Next() % 2];
                Position = new Vector3(pos.X, Position.Y, pos.Y);
                _currentPosition = new Vector3(pos.X, Position.Y, pos.Y);
            }
        }

        public void setInBoundary(Map map)
        {
            Vector3 newPos = _currentPosition;
            if (newPos.X > map.RectRegion.Z)
            {
                newPos.X = map.RectRegion.Z;
            }
            else if (newPos.X < map.RectRegion.X)
            {
                newPos.X = map.RectRegion.X;
            }
            if (newPos.Z > map.RectRegion.W)
            {
                newPos.Z = map.RectRegion.W;
            }
            else if (newPos.Z < map.RectRegion.Y)
            {
                newPos.Z = map.RectRegion.Y;
            }
            Position += newPos - _currentPosition;
            _currentPosition = newPos;


        }

        public bool isCollision(Fighter fighter)
        {
            if (_body == null || fighter._body == null)
                return false;
            for (int i = 0; i < this._body.Length; i++)
            {
                for (int j = 0; j < fighter._body.Length; j++)
                {
                    if (this._body[i].Intersects(fighter._body[j]))
                        return true;
                }
            }
            return false;
        }
        public bool isCollision(Fighter fighter,Move.Strike strike)
        {
            if (strike == Move.Strike.PUNCH)
            {
                if (_hand == null || fighter._body == null)
                    return false;
                for (int i = 0; i < this._hand.Length; i++)
                {
                    for (int j = 0; j < fighter._body.Length; j++)
                    {
                        if (this._hand[i].Intersects(fighter._body[j]))
                            return true;
                    }
                }
            }
            else if (strike == Move.Strike.KICK)
            {
                if (_leg == null || fighter._body == null)
                    return false;
                for (int i = 0; i < this._leg.Length; i++)
                {
                    for (int j = 0; j < fighter._body.Length; j++)
                    {
                        if (this._leg[i].Intersects(fighter._body[j]))
                            return true;
                    }
                }
            }
            return false;
        }

        public void hit(Fighter fighter,float damageRatio)
        {
            if (_tacked)
            {
                if (_lastMove == null)
                    return;
                
                if (isCollision(fighter, _lastMove.StrikeType))
                {
                    Vector3 dPos = fighter.CurrentPosition - this.CurrentPosition ;
                    float direct = GetVecterRotation(dPos);
                    float d = _lastMove.Damage;
                    dPos.Y = 0;
                    fighter.setForce(dPos, d);
                    
                    if (getDeltaRotaionY(direct,RotationY)< MathHelper.PiOver4 &&
                        !(fighter.CurrentState == State.defend 
                        && getDeltaRotaionY(direct + MathHelper.Pi, fighter.RotationY)< MathHelper.PiOver4))
                    {
                        
                        fighter.Hp -= (int)(d * damageRatio);
                        fighter.Hurt();
                    }
                    isPlayHitSound = true;
                }
            }
        }

        public float GetVecterRotation(Vector3 dPos)
        {
            float d = dPos.Length();
            if (d == 0)
                return 0;
            float y = dPos.X;
            float rotationY = (float)Math.Asin(y / d);
            if (dPos.Z < 0)
            {
                rotationY = MathHelper.Pi - rotationY;
            }
            return rotationY;
        }

        protected void createCollisionXML(string outputFile)
        {
            if (!File.Exists(outputFile))
            {
                XmlDocument doc = new XmlDocument();
                XmlElement root = doc.CreateElement("XnaContent");
                doc.AppendChild(root);
                XmlElement eleAsset = doc.CreateElement("Asset");
                eleAsset.SetAttribute("Type", "SkinnedModel.SkinnedSphere[]");
                root.AppendChild(eleAsset);
                for (int i = 0; i < _model.Model.Bones.Count; i++)
                {
                    XmlElement eleItem = doc.CreateElement("Item");                    
                    XmlElement eleBoneName = doc.CreateElement("BoneName");
                    string boneName = _model.Model.Bones[i].Name;  
                    if (boneName.Contains("Bone"))
                    {
                        eleAsset.AppendChild(eleItem);
                        eleBoneName.InnerText = boneName;
                        XmlElement eleRadius = doc.CreateElement("Radius");
                        eleRadius.InnerText = (4).ToString();
                        eleItem.AppendChild(eleBoneName);
                        eleItem.AppendChild(eleRadius);
                    }
                    
                }
                doc.Save(outputFile);
            }
        }

        /// <summary>
        /// Updates the boundingSpheres array to match the current animation state.
        /// </summary>
        void UpdateBoundingSpheres()
        {
            // Look up the current world space bone positions.
            Matrix[] worldTransforms = _animationPlayer.GetWorldTransforms();

            for (int i = 0; i < skinnedSpheres.Length; i++)
            {
                // Convert the SkinnedSphere description to a BoundingSphere.
                SkinnedSphere source = skinnedSpheres[i];
                Vector3 center = new Vector3(source.OffsetX, source.OffsetY, source.OffsetZ);
                BoundingSphere sphere = new BoundingSphere(center, source.Radius);

                // Transform the BoundingSphere by its parent bone matrix,
                // and store the result into the boundingSpheres array.
                int boneIndex = _skinningData.BoneIndices[source.BoneName];

                boundingSpheres[i] = sphere.Transform(worldTransforms[boneIndex]*Matrix.CreateRotationX(-MathHelper.PiOver2)*_model.TransformMatrix/* * Matrix.CreateScale(Scale) * Matrix.CreateTranslation(Position)*/);
            }
            setBoundingSphere();
        }

        /// <summary>
        /// Draws the animated bounding spheres.
        /// </summary>
        public void DrawBoundingSpheres(GraphicsDevice graphicsDevice, Matrix view, Matrix projection)
        {
            if(spherePrimitive == null)
                spherePrimitive = new SpherePrimitive(_graphicsDevice, 1, 12);
            graphicsDevice.RasterizerState = new RasterizerState
            {
                FillMode = FillMode.WireFrame
            }; 

            foreach (BoundingSphere sphere in boundingSpheres)
            {
                Matrix world = Matrix.CreateScale(sphere.Radius) *
                               Matrix.CreateTranslation(sphere.Center);

                spherePrimitive.Draw(world, view, projection, Color.White);
            }

            for (int i = 0; i < energySpheres.Count; i++)
            {
                Matrix world1 = Matrix.CreateScale(energySpheres[i].Bounding.Radius) *
                   Matrix.CreateTranslation(energySpheres[i].Bounding.Center);
                spherePrimitive.Draw(world1, view, projection, Color.White);
            }
            graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        }

        protected void setBoundingSphere()
        {

            _hand = new BoundingSphere[2];
            _hand[0] = boundingSpheres[0];
            _hand[1] = boundingSpheres[1];

            _leg = new BoundingSphere[2];
            _leg[0] = boundingSpheres[2];
            _leg[1] = boundingSpheres[3];

            _body = new BoundingSphere[2];
            _body[0] = boundingSpheres[4];
            _body[1] = boundingSpheres[5];
        }

        static public float getDeltaRotaionY(float alpha, float beta )
        {
            float dR = alpha - beta;
            while (dR >= MathHelper.TwoPi)
                dR -= MathHelper.TwoPi;
            dR = Math.Abs(dR);
            if (dR >= Math.PI)
                dR = MathHelper.TwoPi - dR;
            return dR;
        }

        private void UpdateEnergyShield()
        {
            const int fireParticlesPerFrame = 20;

            // Create a number of fire particles, randomly positioned around a circle.
            for (int i = 0; i < fireParticlesPerFrame; i++)
            {
                _energyShield.AddParticle(_currentPosition + new Vector3(0, 1, 0), Vector3.Zero);
            }            
        }


        //private Vector3 RandomPointOnSphere()
        //{
        //    const float radius = 20f;
        //    const float height = 1f;

        //    double angle1 = gameRandom.NextDouble() * Math.PI * 2;
        //    double angle2 = gameRandom.NextDouble() * Math.PI * 2;

        //    double x = (radius * Math.Cos(angle1) * Math.Sin(angle2));
        //    double y = (radius * Math.Sin(angle1) * Math.Sin(angle2));
        //    double z = (radius * Math.Cos(angle2));

        //    //return (Position + new Vector3((float)x, (float)y + height, (float)z));
        //    return Position;
        //}

        //Vector3 RandomPointOnCircle()
        //{
        //    const float radius = 1;
        //    const float height = 1;

        //    double angle = gameRandom.NextDouble() * Math.PI * 2;

        //    float x = (float)Math.Cos(angle);
        //    float z = (float)Math.Sin(angle);

        //    //return (Position + new Vector3(x * radius, height, z * radius));
        //    return Position;
        //}
        /*public void SetRandomMove(Random r)
        {
            if (r.Next(2) > 0)
            {
            }
            else
            {
            }
        }*/
        public List<Vector3> getExplosionPoint()
        {
            List<Vector3> pos = new List<Vector3>();
            for (int i = 0; i < energySpheres.Count; i++)
            {
                if (energySpheres[i].IsExplosion)
                {
                    energySpheres[i].IsExplosion = false;
                    pos.Add(energySpheres[i].Position);
                }
            }
            return pos;
        }

        public bool isEnergySphereCollision(Fighter fighter)
        {
            bool result = false;
            for (int i = 0; i < fighter.boundingSpheres.Length; i++)
            {
                for (int j = 0; j < energySpheres.Count; j++)
                    if (energySpheres[j].Bounding.Intersects(fighter.boundingSpheres[i]))
                    {
                        SetEnergyExplosion(energySpheres[j]);
                        result = true;
                    }
            }
            return result;
        }

        private void SetEnergyExplosion(EnergySphere en)
        {
            en.IsCollision = true;
            en.IsExplosion = true;
            _explosionSoundPoint.Add(en.Position);
        }

    }
}
